/* 包含头文件-----------------------------------------------------------------*/
#include "gpio.h"

/* 私有宏定义-----------------------------------------------------------------*/
/* GPIO使用到的时钟 */
#define GPIO_USED_CLK                       (RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC)
/* GPIO基础操作API */
#define GPIO_TOGGLE(port, pin)              ((port)->BSRR = (((port)->ODR & (pin)) << 16) | (~(port)->ODR & (pin)))
#define GPIO_SET(port, pin)                 ((port)->BSRR = (uint32_t)(pin))
#define GPIO_RESET(port, pin)               ((port)->BSRR = (uint32_t)(pin) << 16)
#define GPIO_READ(port, pin)                (((port)->IDR & (pin)) != 0)
/* 用户实现的GPIO端口和引脚宏定义 */
/* LED_RUN 0点亮 1熄灭 */
#define LED_RUN_GPIO_PORT                   (GPIOA)
#define LED_RUN_GPIO_PIN                    (GPIO_Pin_11)
/* TEST_IN */
#define TEST_IN_GPIO_PORT                   (GPIOA)
#define TEST_IN_GPIO_PIN                    (GPIO_Pin_2)
/* BT_RST */
#define BT_RST_GPIO_PORT                    (GPIOC)
#define BT_RST_GPIO_PIN                     (GPIO_Pin_15)
/* BT_PWR */
#define BT_PWR_GPIO_PORT                    (GPIOB)
#define BT_PWR_GPIO_PIN                     (GPIO_Pin_5)

/* 私有类型定义---------------------------------------------------------------*/

/* 私有变量-------------------------------------------------------------------*/

/* 全局变量-------------------------------------------------------------------*/

/* 私有函数原型---------------------------------------------------------------*/

/**
  * @brief  GPIO初始化
  * @param  None
  * @retval None
  */
void gpio_config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    RCC_APB2PeriphClockCmd(GPIO_USED_CLK, ENABLE); /* 开启GPIO时钟 */
    
    GPIO_InitStructure.GPIO_Pin = LED_RUN_GPIO_PIN; /* 设置引脚号 */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /* 设置引脚模式 */
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* 设置引脚速度 */
    GPIO_Init(LED_RUN_GPIO_PORT, &GPIO_InitStructure); /* 初始化GPIO */
    
    GPIO_InitStructure.GPIO_Pin = BT_RST_GPIO_PIN;
    GPIO_Init(BT_RST_GPIO_PORT, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = BT_PWR_GPIO_PIN;
    GPIO_Init(BT_PWR_GPIO_PORT, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = TEST_IN_GPIO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(TEST_IN_GPIO_PORT, &GPIO_InitStructure);

    /* gpio default state */
    gpio_set(LED_RUN);
    gpio_reset(BT_RST);
    gpio_set(BT_PWR);
}

/**
  * @brief  IO置高
  * @param  gpiox : gpio枚举名称 @ref gpiox_enum_t
  * @retval None
  */
void gpio_set(uint8_t gpiox)
{
    switch(gpiox)
    {
        case LED_RUN: GPIO_SET(LED_RUN_GPIO_PORT, LED_RUN_GPIO_PIN); break;
        case TEST_IN: GPIO_SET(TEST_IN_GPIO_PORT, TEST_IN_GPIO_PIN); break;
        case BT_RST: GPIO_SET(BT_RST_GPIO_PORT, BT_RST_GPIO_PIN); break;
        case BT_PWR: GPIO_SET(BT_PWR_GPIO_PORT, BT_PWR_GPIO_PIN); break;
    }
}

/**
  * @brief  IO置低
  * @param  gpiox : gpio枚举名称 @ref gpiox_enum_t
  * @retval None
  */
void gpio_reset(uint8_t gpiox)
{
    switch(gpiox)
    {
        case LED_RUN: GPIO_RESET(LED_RUN_GPIO_PORT, LED_RUN_GPIO_PIN); break;
        case TEST_IN: GPIO_RESET(TEST_IN_GPIO_PORT, TEST_IN_GPIO_PIN); break;
        case BT_RST: GPIO_RESET(BT_RST_GPIO_PORT, BT_RST_GPIO_PIN); break;
        case BT_PWR: GPIO_RESET(BT_PWR_GPIO_PORT, BT_PWR_GPIO_PIN); break;
    }
}

/**
  * @brief  IO翻转
  * @param  gpiox : gpio枚举名称 @ref gpiox_enum_t
  * @retval None
  */
void gpio_toggle(uint8_t gpiox)
{
    switch(gpiox)
    {
        case LED_RUN: GPIO_TOGGLE(LED_RUN_GPIO_PORT, LED_RUN_GPIO_PIN); break;
        case TEST_IN: GPIO_TOGGLE(TEST_IN_GPIO_PORT, TEST_IN_GPIO_PIN); break;
        case BT_RST: GPIO_TOGGLE(BT_RST_GPIO_PORT, BT_RST_GPIO_PIN); break;
        case BT_PWR: GPIO_TOGGLE(BT_PWR_GPIO_PORT, BT_PWR_GPIO_PIN); break;
    }
}

/**
  * @brief  IO读取
  * @param  gpiox : gpio枚举名称 @ref gpiox_enum_t
  * @retval 0:low level  1:high level
  */
uint8_t gpio_read(uint8_t gpiox)
{
    uint8_t temp = 0;
    
    switch(gpiox)
    {
        case LED_RUN: temp = GPIO_READ(LED_RUN_GPIO_PORT, LED_RUN_GPIO_PIN); break;
        case TEST_IN: temp = GPIO_READ(TEST_IN_GPIO_PORT, TEST_IN_GPIO_PIN); break;
        case BT_RST: temp = GPIO_READ(BT_RST_GPIO_PORT, BT_RST_GPIO_PIN); break;
        case BT_PWR: temp = GPIO_READ(BT_PWR_GPIO_PORT, BT_PWR_GPIO_PIN); break;
    }
    
    return temp;
}
